home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / Icon 8.1 / msm-1 / icont.sit / ixhdr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-19  |  6.4 KB  |  276 lines  |  [TEXT/MPS ]

  1. /*
  2.  * ixhdr.c -- bootstrap header for icode files
  3.  */
  4.  
  5. #include "::h:gsupport.h"
  6. #include "tproto.h"
  7.  
  8. #if UNIX
  9. #ifdef Header
  10. #include "::h:header.h"
  11. #include <stdio.h>
  12. #include <sys/types.h>
  13. #include <sys/stat.h>
  14.  
  15. /*
  16.  * Prototypes.
  17.  */
  18.  
  19. hidden    novalue    doiconx        Params((char **s, char *t));
  20. hidden    novalue    hsyserr        Params((char *av, char *file));
  21.  
  22. #if IntBits == 16
  23. #undef strlen            /* short versions used here */
  24. #endif                    /* IntBits == 16 */
  25.  
  26. static char patchpath[MaxPath+18] = "%PatchStringHere->";
  27. static char *refpath = RefPath;
  28.  
  29. novalue main(argc, argv)
  30. int argc;
  31. char **argv;
  32.    {
  33.    char fullpath[256];
  34.    char *name;
  35.    char *argvx[1000];
  36.  
  37.    /*
  38.     * Abort if we've been invoked with setuid or setgid privileges.
  39.     *  Allowing such usage would open a huge security hole, because
  40.     *  there is no way to ensure that the right iconx will interpret
  41.     *  the right user program.
  42.     */
  43.    if (getuid() != geteuid() || getgid() != getegid())
  44.       hsyserr(argv[0], ": cannot run an Icon program setuid/setgid");
  45.  
  46.    name = argv[0];            /* name of icode file */
  47.  
  48.    do 
  49.       argvx[argc+1] = argv[argc];
  50.    while (argc--);
  51.    argv = argvx;
  52.  
  53.    /*
  54.     * If the name contains any slashes, execute the file as named.
  55.     *  Otherwise, search the path to find out where the file really is.
  56.     */
  57.    if (index(name, '/'))
  58.       doiconx(argv, name);
  59.    else if (findcmd(fullpath, name, "PATH"))
  60.       doiconx(argv, fullpath);
  61.    else
  62.       hsyserr("iconx: icode file not found: ", fullpath);
  63.    }
  64.  
  65. /*
  66.  * doiconx(argv, file) - execute iconx, passing file as argv[1].
  67.  *
  68.  *  To find the interpreter, first check the environment variable ICONX.
  69.  *  If it defines a path, it had better work, else we abort.
  70.  *
  71.  *  If there's no $ICONX, but there's a hardwired path, try that.
  72.  *  If THAT doesn't work, try searching $PATH for an "iconx" program.
  73.  *  If nothing works, abort.
  74.  */
  75. static novalue doiconx(argv, file)
  76. char **argv;
  77. char *file;
  78.    {
  79.    char xcmd[256];
  80.  
  81. #ifdef HardWiredPaths
  82.    static char hardpath[MaxPath];
  83.  
  84.    if ((strlen(refpath) + 6) > MaxPath)
  85.       hsyserr("path to iconx too long","");
  86.    strcpy(hardpath, refpath);
  87.    strcat(hardpath, "iconx");
  88.  
  89.    if (strlen(patchpath)>18)
  90.       strcpy(hardpath, patchpath+18);
  91. #endif                    /* HardWiredPaths */
  92.  
  93.    argv[1] = file;
  94.  
  95.    if ((argv[0] = getenv("ICONX")) != NULL && argv[0][0] != '\0') {
  96.       execv(argv[0], argv);        /* exec file specified by $ICONX */
  97.       hsyserr("cannot execute $ICONX: ", argv[0]);
  98.       }
  99.  
  100. #ifdef HardWiredPaths
  101.    argv[0] = hardpath;            /* try predefined file */
  102.    execv(hardpath, argv);
  103. #endif                    /* HardWiredPaths */
  104.  
  105.    if (findcmd(xcmd, "iconx", "PATH")) {
  106.       argv[0] = xcmd;
  107.       execv(xcmd, argv);    /* if no path, search path for "iconx" */
  108.       hsyserr("cannot execute ", xcmd);
  109.       }
  110.  
  111. #ifdef HardWiredPaths
  112.    hsyserr("cannot execute ", hardpath);
  113. #else                    /* HardWiredPaths */
  114.    hsyserr("cannot find iconx", "");
  115. #endif                    /* HardWiredPaths */
  116.    }
  117.  
  118. /*
  119.  * hsyserr(s1, s2) - print s1 and s2 on stderr, then abort.
  120.  */
  121. hidden novalue hsyserr(s1, s2)
  122. char *s1, *s2;
  123.    {
  124.    char s[100];
  125.    /*
  126.     * Low-level I/O is used here to avoid sucking in a lot of stuff
  127.     *  that would make iconx.hdr much larger.
  128.     */
  129.    strcpy(s, s1);
  130.    if (s2)
  131.       strcat(s, s2);
  132.    strcat(s, "\n");
  133.    write(2, s, strlen(s));
  134.    _exit(ErrorExit);
  135.    }
  136.  
  137. /*
  138.  * This function searches all the directories in the path style environment
  139.  * variable (pvar) for a command with the base name (cnam).  If the command
  140.  * is found its full name is stored in the pointer passed (cmd) and 1 is
  141.  * returned.  If the command isn't found 0 is returned.
  142.  */
  143.  
  144. int    findcmd(cmd,cnam,pvar)
  145. register
  146. char    *cmd,
  147.     *cnam,
  148.     *pvar;
  149. {
  150.     register
  151.     char    *path;
  152.  
  153.     char    pbuf[1024],
  154.         *getdir(),
  155.         *getenv();
  156.  
  157. /*    if the environment variable isn't defined give up */
  158.     if (! (path = getenv(pvar))) return 0;
  159.  
  160. /*    copy the path to a temporary path buffer and point at the buffer
  161.  *    (this is necessary because we can diddle its contents in getdir) */
  162.     strcpy(pbuf,path);
  163.     path = pbuf;
  164.  
  165. /*    loop through all the path variable directories and check for
  166.  *    the command in each */
  167.     while (path = getdir(cmd,path)) {
  168.         strcat(cmd,cnam);
  169.         if (chkcmd(cmd)) return 1;
  170.     }
  171.  
  172.     return 0;
  173. }
  174.  
  175. /*
  176.  * This function returns the next directory in the directory string passed
  177.  * in path.  This directory string is similar to the PATH environment
  178.  * variable.  A pointer to the remaining directory string is returned so
  179.  * that the entire string can be scanned by the calling function.
  180.  */
  181.  
  182. char    *getdir(dir,path)
  183. register
  184. char    *dir,    /* the command directory buffer */
  185.     *path;    /* the string of directories */
  186. {
  187.     register
  188.     char    *dp;    /* the original directory pointer */
  189.  
  190. /*    if there is nothing left return null */
  191.     if (! *path) return (char *) 0;
  192.  
  193. /*    save the original directory pointer */
  194.     dp = dir;
  195.  
  196. /*    copy up to the next separator or the end of path */
  197.     while (*path && *path != ':') *dir++ = *path++;
  198.  
  199. /*    if dir is still empty use a dot (the current directory */
  200.     if (dp == dir) *dir++ = '.';
  201.  
  202. /*    if the directory isn't terminated with a slash tack one on */
  203.     if (*(dir-1) != '/') *dir++ = '/';
  204.  
  205. /*    null terminate the directory */
  206.     *dir = 0;
  207.  
  208. /*    if there's still a colon in path */
  209.     if (*path) {
  210.  
  211. /*        if there's something after the colon skip the colon */
  212.         if (*(path+1)) path++;
  213.  
  214. /*        otherwise terminate path with a dot (the current directory) */
  215.         else *path = '.';
  216.     }
  217.  
  218.     return path;
  219. }
  220.  
  221. /*
  222.  * This function checks to see if the file name passed exists and is
  223.  * executable.
  224.  */
  225.  
  226. #ifndef    S_IFMT        /* defined in <sys/stat.h> */
  227. #include <sys/types.h>
  228. #include <sys/stat.h>
  229. #endif                    /* S_IFMT */
  230.  
  231. int    chkcmd(file)
  232. register
  233. char    *file;
  234. {
  235.     register
  236.     unsigned
  237.     short    gid, uid;
  238.  
  239.     struct    stat s;
  240.  
  241. /*    if the file can't be "stat"ed fail */
  242.     if (stat(file,&s) < 0) return 0;
  243.  
  244. /*    get the effective group and user ids for this user */
  245.     gid = getegid();
  246.     uid = geteuid();
  247.  
  248. /*    if this is a "regular" file AND */
  249.     if ((s.st_mode & 0100000) &&
  250.  
  251. /*    the execute bit is set for "other" and the group id and user id
  252.  *    don't match OR */
  253.        (((s.st_mode & 0000001) && s.st_gid != gid && s.st_uid != uid) ||
  254.  
  255. /*    the execute bit is set for "group" and the group id matches and
  256.  *    the user id doesn't OR */
  257.         ((s.st_mode & 0000010) && s.st_gid == gid && s.st_uid != uid) ||
  258.  
  259. /*    the execute bit is set for "user" and the user id matches THEN */
  260.         ((s.st_mode & 0000100) && s.st_uid == uid)))
  261.  
  262. /*        succeed */
  263.         return 1;
  264.  
  265. /*    otherwise fail */
  266.     return 0;
  267. }
  268.  
  269. #else                    /* Header */
  270. main() {}
  271. #endif                    /* Header */
  272.  
  273. #else                    /* UNIX */
  274. main() {}
  275. #endif                    /* UNIX */
  276.